import { Link } from '@brillout/docpress'

> **What is preloading?** Preloading denotes the practice of loading assets (JavaScript, CSS, images, etc.) before the browser discovers them in HTML/CSS/JavaScript code. That way you can reduce the network round trips required before the browser starts discovering and loading all dependencies.

By default, Vike automatically inject tags to your HTML such as:
- `<script type="module" src="script.js">`
- `<link rel="stylesheet" type="text/css" href="style.css">`
- `<link rel="preload" href="font.ttf" as="font" type="font/ttf">`

It does so using a preload strategy that works for most users, but you can use <Link href="#injectfilter" /> to implement a custom preload strategy.

To improve preloading performance, you can use <Link href="#early-hints" /> which Vike automatically generates.

> See also <Link href="/prefetchStaticAssets" />.


## Early Hints

> The [Early Hints Header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/103) is the official successor of the now deprecated HTTP2/Push.

```js
// server.js

import { renderPage } from 'vike/server'

app.get('*', async (req, res) => {
  const pageContext = await renderPage({ urlOriginal: req.originalUrl } )
  const { earlyHints } = pageContext.httpResponse
  // For example with Node.js 18:
  res.writeEarlyHints({ link: earlyHints.map((e) => e.earlyHintLink) })
})
```

```ts
type PageContext = {
  httpResponse: {
    earlyHints: {
      earlyHintLink: string // Header Line for the Early Hint Header
      assetType: "image" | "script" | "font" | "style" | "audio" | "video" | "document" |
                 "fetch" | "track" | "worker" | "embed" | "object" | null
      mediaType: string // MIME type
      src: string // Asset's URL
      isEntry: boolean // true  ⇒ asset is an entry
                       // false ⇒ asset is a dependency of an entry
    }[]
  }
}
```

See also:
 - [developer.chrome.com > Early Hints](https://developer.chrome.com/blog/early-hints/)
 - [Node.js 18 Support](https://nodejs.org/dist/latest-v19.x/docs/api/http.html#responsewriteearlyhintshints-callback)
 - <Link href="/nginx#early-hints" />


## `injectFilter()`

If Vike's default preload strategy doesn't work for you, you can customize which and where preload/asset tags are injected.

```ts
// /renderer/+onRenderHtml.js

export { onRenderHtml }

async function onRenderHtml(pageContext) {
  // ...

  const documentHtml = escapeInject`<!DOCTYPE html>
    <html>
      <body>
        <div id="page-view">${stream}</div>
      </body>
    </html>`

  const injectFilter = (assets) => {
    assets.forEach(asset => {
      // Preload images
      if (asset.assetType === 'image') {
        asset.inject = 'HTML_BEGIN'
      }
    })
  }

  return { documentHtml, injectFilter }
}
```

See <Link href="/injectFilter" />.


## Assets Manifest

By using <Link href="/getGlobalContext">`getGlobalContextSync()` or `getGlobalContextAsync()`</Link>, you can access the so-called "assets manifest": the dependency graph of your app's static assets.

> The assets manifest is only available in production.


## See also

- <Link href="/injectFilter" />
- <Link href="/prefetchStaticAssets" />
- <Link href="/streaming" />
- <Link href="/getGlobalContext" />
